Amazon AuroraのヘッドレスDBクラスターを作成してみた
当分の間DBを使用する予定はないのでDBインスタンスはしばらく停止し続けたい
こんにちは、のんピ(@non____97)です。
皆さんはAmazon Auroraを使用していて「当分の間DBを使用する予定はないのでDBインスタンスはしばらく停止し続けたい」と思ったことはありますか? 私はあります。
RDSやAuroraのDBインスタンス、DBクラスターを停止できるのは最大7日です。7日経過すると自動で起動してきます。直接7日以上停止することはできません。もし7日以上停止し続けたいのであれば、DBインスタンスやDBクラスターが起動してきたら停止するというEventBridge RuleとLambda関数 or Step Functionsが必要だと考えます。
Auroraを使っている場合、そんなお悩みはヘッドレスDBクラスターとすることで問題を解決できるかもしれません。
Auroraではストレージとコンピューティングが分離しています。
抜粋 : Amazon Aurora DB クラスター - Amazon Aurora
そのため、AuroraのDBインスタンスを削除して、DBクラスター内に何もインスタンスが存在しない状態(ヘッドレスDBクラスター)としても、ストレージ内にデータは残り続けます。データを取り出したい、DBとして動作させたい場合はDBインスタンスを起動すれば良いだけです。
実際にやってみました。
いきなりまとめ
- 全てのAurora DBインスタンスを削除しても、DBインスタンスを再作成すれば、DBクラスター内のデータにアクセスできる
- ヘッドレスDBクラスターでもDBクラスターのスナップショットは取得できる
- 以下の操作はマネジメントコンソールから行えない
- ヘッドレスDBクラスターへのDBインスタンスの作成
- ヘッドレスDBクラスターの状態では以下の操作はできない
- Data APIを使ったクエリ実行
- Global Databaseの作成
- クローンの作成
- PITR
- S3へのエクスポート
- 正直、長期間起動させないのであれば、スナップショットからリストアした方が良いように思える
- バックアップストレージの料金 : 0.023 USD/GB
- Aurora Standardのストレージの料金 : 0.12 USD/GB
やってみた
検証環境
検証環境は以下のとおりです。Aurora PostgreSQLと操作用のEC2インスタンスを1つづつ作成します。
なお、構成は以下記事で紹介しているものです。
検証環境はAWS CDKでデプロイしました。使用したコードは以下リポジトにあります。
Aurora DBクラスターの作成
それではAurora DBクラスターの作成をします。
npx cdk deploy
でデプロイして10分ほどでAurora DBクラスターとDBインスタンスが起動完了しました。
DBへのデータの投入
DBへデータを投入します。
下準備としてSecrets Managerに保存されている認証情報を環境変数に保存します。
$ get_secrets_value=$(aws secretsmanager get-secret-value \
--secret-id AuroraSecret7ACECA7F-BLZxpBZDcJDq \
--region us-east-1 \
| jq -r .SecretString)
$ export PGHOST=$(echo "${get_secrets_value}" | jq -r .host)
$ export PGPORT=$(echo "${get_secrets_value}" | jq -r .port)
$ export PGDATABASE=$(echo "${get_secrets_value}" | jq -r .dbname)
$ export PGUSER=$(echo "${get_secrets_value}" | jq -r .username)
$ export PGPASSWORD=$(echo "${get_secrets_value}" | jq -r .password)
PostgreSQLが提供しているサンプルデータを投入します。
$ curl https://ftp.postgresql.org/pub/projects/pgFoundry/dbsamples/iso-3166/iso-3166-1.0/iso-3166-1.0.tar.gz \
-s \
-o iso-3166-1.0.tar.gz
$ tar zxvf iso-3166-1.0.tar.gz
iso-3166/
iso-3166/iso-3166.sql
$ createdb iso
$ psql -f iso-3166/iso-3166.sql iso
BEGIN
SET
CREATE TABLE
COPY 242
CREATE TABLE
COPY 3995
COMMIT
ANALYZE
ANALYZE
サンプルデータ投入後、DBに接続してレコードが登録されていることを確認します。
$ psql iso
psql (15.6, server 14.10)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.
iso=> \dt
List of relations
Schema | Name | Type | Owner
--------+------------+-------+----------
public | country | table | postgres
public | subcountry | table | postgres
(2 rows)
iso=> SELECT count(*) FROM country;
count
-------
242
(1 row)
iso=> SELECT count(*) FROM subcountry;
count
-------
3995
(1 row)
DBインスタンスの削除
DBインスタンスを削除します。AWS CDKでAurora DBクラスターを作成したので、DBインスタンスの削除もAWS CDKから行います。
具体的には以下のようにDBクラスターからDBインスタンスを探してきて、tryRemoveChild()
で削除するコードを追加します。
this.dbCluster.node.children.forEach((child) => {
if (child.node.defaultChild instanceof cdk.aws_rds.CfnDBInstance) {
this.dbCluster.node.tryRemoveChild(child.node.id);
}
});
npx cdk diff
をすると、確かにDBインスタンスのみを削除してくれそうです。
$ npx cdk diff
Stack AuroraStack
Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff)
Resources
[-] AWS::RDS::DBInstance Aurora/Default/Writer AuroraWriter14FF9353 destroy
✨ Number of stacks with differences: 1
npx cdk deploy
を叩いて15分弱でDBクラスター内からのDBインスタンスの削除が完了しました。
DBへ接続しようとしても当然ながら弾かれます。
$ psql iso
psql: error: could not translate host name "db-cluster.cluster-cicjym7lykmq.us-east-1.rds.amazonaws.com" to address: Name or service not known
そもそも、DBクラスターエンドポイントを名前解決しても、DBインスタンスが存在しないため結果が返ってきません。
$ dig db-cluster.cluster-cicjym7lykmq.us-east-1.rds.amazonaws.com
; <<>> DiG 9.16.48-RH <<>> db-cluster.cluster-cicjym7lykmq.us-east-1.rds.amazonaws.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 2256
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;db-cluster.cluster-cicjym7lykmq.us-east-1.rds.amazonaws.com. IN A
;; ANSWER SECTION:
db-cluster.cluster-cicjym7lykmq.us-east-1.rds.amazonaws.com. 5 IN CNAME db-instance-writer.cicjym7lykmq.us-east-1.rds.amazonaws.com.
;; AUTHORITY SECTION:
us-east-1.rds.amazonaws.com. 10 IN SOA ns-1420.awsdns-49.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400
;; Query time: 0 msec
;; SERVER: 10.1.1.2#53(10.1.1.2)
;; WHEN: Sun Mar 24 08:31:31 UTC 2024
;; MSG SIZE rcvd: 216
ちなみにマネジメントコンソールからDBインスタンスを削除してもヘッドレスDBクラスターになります。
DBクラスターのスナップショットを取得できることを確認
DBクラスターのスナップショットが取得できるか気になったので試してみます。データの変化は発生しませんが、自動バックアップがコケ続けることにより、最後に正常に取得できたスナップショットの有効期限が切れるのは避けたいです。
マネジメントコンソールからDBクラスターのスナップショットを取得します。
すると、1分ほどでスナップショットの取得が完了しました。
DBクラスターのスナップショットを取得できるのであれば、自動バックアップがコケてしまうこともなさそうです。
ヘッドレスDBクラスターでできない操作を確認
続いて、ヘッドレスDBクラスターでできない操作を確認してみます。
マネジメントコンソールでDBクラスターのアクションをクリックすると、以下のようにグレーアウトされている項目がいくつかあります。
また、WriterのDBインスタンスを作成することも出来なさそうです。
実際にいくつか操作してみます。
Global Databaseを作成しようとすると、このクラスターおよび関連付けられたインスタンスは現在作成中です。作成が完了しクラスターが使用可能になると、グローバルデータベースを作成してリージョンを追加できるようになります。
とDBインスタンスが存在しないのは、DBインスタンスを作成していると判断して作成させてくれませんでした。
レプリカを追加しようとすると、DBInstance db-instance-writer not found.
とDBインスタンスがないため弾かれました。
クローンの作成やPITRをしようとすると、The parameter Filter: dbi-resource-id is not a valid DbiResourceId. The DbiResourceId must begin with db- prefix; remaining part must contain only ASCII letters and digits; and must not be empty.
とDBインスタンスがないため怒られました。
S3へのエクスポートを行おうとすると、The source cluster DBクラスターのARN can't be exported because it doesn't have an instance.
と怒られました。
Data APIからのリクエストを行おうとすると、DBインスタンスがないと怒られました。
$ aws rds-data execute-statement \
--resource-arn arn:aws:rds:us-east-1:<AWSアカウントID>:cluster:db-cluster \
--secret-arn arn:aws:secretsmanager:us-east-1:<AWSアカウントID>:secret:AuroraSecret7ACECA7F-BLZxpBZDcJDq-sGEKy7 \
--database iso \
--sql 'SELECT count(*) FROM country;'
An error occurred (DatabaseNotFoundException) when calling the ExecuteStatement operation: Cannot find DBInstance in DBCluster arn:aws:rds:us-east-1:<AWSアカウントID>:cluster:db-cluster.
よくよくドキュメントを見てみると、Data APIのクエリはWriterインスタンスで実行されると記載されていますね。
Data API クエリは、DB クラスターのライターインスタンスでのみ実行できます。ただし、ライターインスタンスは書き込みクエリと読み取りクエリの両方を受け入れることができます。
ちなみにData APIの有効化/無効化はヘッドレスDBクラスターでも行えました。
DBインスタンスの再作成
DBインスタンスの再作成を行います。
DBインスタンスを削除するために追加したコードを削除して、再度デプロイします。
npx cdk diff
をすると、DBインスタンスが追加されることが分かります。
$ npx cdk diff
Stack AuroraStack
Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff)
Resources
[+] AWS::RDS::DBInstance Aurora/Default/Writer AuroraWriter14FF9353
✨ Number of stacks with differences: 1
npx cdk deploy
後、10分弱でDBインスタンスの起動が完了しました。
DBインスタンス削除前に投入したデータにアクセスできるか確認
それでは、DBインスタンス削除前に投入したデータにアクセスできるか確認してみましょう。
$ psql iso
psql (15.6, server 14.10)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.
iso=> \dt
List of relations
Schema | Name | Type | Owner
--------+------------+-------+----------
public | country | table | postgres
public | subcountry | table | postgres
(2 rows)
iso=> SELECT count(*) FROM country;
count
-------
242
(1 row)
iso=> SELECT count(*) FROM subcountry;
count
-------
3995
(1 row)
iso=> SELECT * FROM country LIMIT 10;
name | two_letter | country_id
---------------------+------------+------------
Afghanistan | AF | 4
Albania | AL | 8
Algeria | DZ | 12
American Samoa | AS | 16
Andorra | AD | 20
Angola | AO | 24
Anguilla | AI | 660
Antarctica | AQ | 10
Antigua and Barbuda | AG | 28
Argentina | AR | 32
(10 rows)
iso=> SELECT * FROM subcountry LIMIT 10;
country | subcountry_name | subdivision | subcountry_level
---------+-----------------+-----------------------+------------------
AD | AN | Andorra la Vella |
AD | CA | Canillo |
AD | EE | Escaldes-Engordany |
AD | EN | Encamp |
AD | JL | Sant Julià de Lòria |
AD | MA | La Massana |
AD | OR | Ordino |
AE | AJ | Ajman |
AE | AZ | Abu Z¸aby [Abu Dhabi] |
AE | DU | Dubayy [Dubai] |
(10 rows)
確かにDBインスタンスを削除しても、ストレージ内にあるデータは削除されずに残っていることが分かりました。
DBインスタンスを長期間停止したいのであれば、一時的に削除するのも選択肢に
Amazon AuroraのヘッドレスDBクラスターを紹介しました。
Auroraがコンピューティングとストレージが分離していることがよく分かりますね。
なお、DBインスタンスの停止がコスト削減であり、長期間起動させないのであればスナップショットからリストアした方がコスト効率が良いように思えます。
料金を比較すると以下のとおりです。
- バックアップストレージの料金 : 0.023 USD/GB
- Aurora Standardのストレージの料金 : 0.12 USD/GB
Autoraのバックアップ料金の考え方は以下記事にまとまっています。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!